/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package simhya.simengine.utils;
import simhya.simengine.ProgressMonitor;
import java.io.PrintStream;
import java.util.Locale;

/**
 *
 * @author Luca
 */
public class PrintStreamProgressMonitor implements ProgressMonitor {
    private PrintStream stream;
    private double finalTime;
    public double initialTime;
    private double granularity;
    private double currentPercentage;
    private long simTime;
    private double deltaTime;
    private long totalSteps;
    private long currentStep;

    public PrintStreamProgressMonitor(PrintStream stream) {
        this.stream = stream;
        initialTime = 0;
        finalTime = 0;
        totalSteps = 1;
        currentStep = 0;
        this.granularity = 0.05;
        deltaTime = finalTime-initialTime;
    }
    
    public double getLastSimulationTimeInMillisecs() {
        return (double)(simTime)/1000000;
    }

    public double getLastSimulationTimeInSecs() {
        return (double)(simTime)/1000000000;
    }

    public void setFinalTime(double finalTime) {
        this.finalTime = finalTime;
        deltaTime = finalTime-initialTime;
    }

    public void setInitialTime(double initialTime) {
        this.initialTime = initialTime;
        deltaTime = finalTime-initialTime;
    }

    public void setTotalSteps(long steps) {
        this.totalSteps = steps;
    }



    public void setProgress(double currentTime) {
        if (currentTime > deltaTime*currentPercentage) {
            double eta = (1-currentPercentage)*(double)(System.nanoTime() - simTime)/1000000000;
            stream.println(String.format(Locale.UK, "%.2f", currentPercentage*100)
                    + "% completed. Remaining time: " + String.format(Locale.UK, "%.3f", eta) + " seconds ");
            currentPercentage += this.granularity;
        }
    }

    public void setGranularity(double g) {
        this.granularity = g;
    }

    public void nextStep() {
        this.currentStep++;
        double time = (double)(System.nanoTime() - simTime)/1000000000;
        double eta = (double)(totalSteps-currentStep) * time /(double)currentStep;
        if (this.currentStep < this.totalSteps)
            stream.println("Completed step " + currentStep + " of " + totalSteps + ". "
                    + "Remaining time: " + String.format(Locale.UK, "%.3f", eta) + " seconds ");
        else
            stream.println("Completed in time " + String.format(Locale.UK, "%.3f", time) + " seconds ");
    }



    public void start() {
        this.currentPercentage = this.granularity;
        simTime = System.nanoTime();
    }

    public void stop() {
        simTime = System.nanoTime() - simTime;
    }


    


}
